import math

import topo1


def calculate_communication_delay(topo, communication_pairs, traffic_demands):
    """
    计算所有通信对的端到端延迟
    参数:
        topo: NetworkX图对象，边需包含 'capacity' 属性
        communication_pairs: 字典，键为通信对 (src, dst)，值为路径列表
        traffic_demands: 字典，键为通信对 (src, dst)，值为流量需求（单位：Gbps）
    返回:
        dict: 键为通信对，值为延迟（单位：秒）
    """
    delays = {} # 存储所有通信对的延迟

    # 遍历所有通信对和路径
    for pair, path in communication_pairs.items():
        # 初始化路径最大延迟
        max_link_delay = 0.0  # 初始化最大链路延迟
        # 如果通信对之间没有通信需求则跳过计算该通信对
        if pair not in traffic_demands:
            print(f"警告: 通信对 {pair} 无流量需求，跳过计算")
            delays[pair] = float('inf')
            continue

        total_delay = 0.0
        demand = traffic_demands[pair]
        valid_path = True

        # 遍历路径中的每条链路
        for i in range(len(path) - 1):
            u, v = path[i], path[i + 1]

            # 检查链路是否存在
            if not topo.has_edge(u, v):
                print(f"错误: 通信对 {pair} 路径包含无效链路 {u}→{v}")
                valid_path = False
                break

            # 获取链路容量
            # 初始化路径中链路的最小容量
            capacity = topo[u][v].get('capacity', 0)
            if capacity <= 0:
                print(f"错误: 链路 {u}→{v} 容量 {capacity}Gbps 无效")
                valid_path = False
                break
            # TODO：考虑如何计算链路延迟
            # 计算单链路延迟（假设流量全部占用链路）
            print(f"链路 {u}→{v} 容量 {capacity}Gbps")
            link_delay = demand / capacity  # 单位：秒（Gbps / Gbps → 秒）
            max_link_delay=max(max_link_delay,link_delay)

        if valid_path:
            delays[pair] = round(max_link_delay, 4) #如果路径有效，则将总延迟四舍五入保留4位小数后存储
        else:
            delays[pair] = float('inf') # 如果路径无效，则将总延迟设置为无穷大

    return delays

# 网络拓扑结构（使用NetworkX图结构）
# 每条边包含 'capacity' 属性（单位：Gbps）
import networkx as nx

# topo = nx.DiGraph()
# topo.add_edges_from([
#     ("ToR1", "Aggr1", {"capacity": 40}),
#     ("Aggr1", "Core1", {"capacity": 100}),
#     ("Core1", "Aggr2", {"capacity": 100}),
#     ("Aggr2", "ToR2", {"capacity": 40}),
# ])
topo=topo1.build_hybrid_topology_shared_tor(4)

# 通信对及其路径
communication_pairs = {
    ("ToR3", "ToR1"): ["ToR3", "Optical_SW1", "ToR1"]
}

# 每个通信对的流量需求（单位：Gbps）
traffic_demands = {
    ("ToR3", "ToR1"): 35
}

# 计算所有通信对的延迟
delay_results = calculate_communication_delay(topo, communication_pairs, traffic_demands)

# 打印结果

for pair, delay in delay_results.items():
    src, dst = pair
    path = communication_pairs[pair]
    demand = traffic_demands[pair]

    if not math.isfinite(delay):
        print(f"通信对 {src}→{dst} 路径无效")
        continue

    print(f"通信对: {src} → {dst}")
    print(f"路径: {' → '.join(path)}")
    print(f"流量需求: {demand}Gbps")
    print(f"总延迟: {delay} 秒")
    print("-" * 40)